package com.zeus.core.log.appender;

import com.zeus.common.log.ZeusLoggerConfig;
import com.zeus.common.utils.StackTraceUtils;
import com.zeus.core.context.ZeusContext;
import com.zeus.core.report.ZeusReportClient;
import com.zeus.core.report.ZeusReportLog4j2Client;
import com.zeus.core.report.ZeusReportLog4jClient;
import org.apache.log4j.spi.ThrowableInformation;
import org.apache.logging.log4j.Level;
import org.apache.logging.log4j.core.LogEvent;
import org.apache.logging.log4j.core.appender.AbstractAppender;
import org.apache.logging.log4j.core.config.Property;
import org.apache.logging.log4j.core.layout.PatternLayout;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.Serializable;

/**
 * Log4j日志监控Appender
 *
 * @author wangfeixiong126@gmail.com  2021/4/28 10:40
 */
public class Log4j2MonitorAppender extends AbstractAppender {
    private final static Logger logger = LoggerFactory.getLogger(Log4j2MonitorAppender.class);

    public Log4j2MonitorAppender(PatternLayout layout) {
        super("log4j2MonitorAppender", null, layout, false, Property.EMPTY_ARRAY);
    }

    /**
     * 获取堆栈信息
     *
     * @param throwableInformation throwableInformation
     * @return 堆栈信息
     * @author f1ybear_wang  2022/2/8 6:36 下午
     */
    private String getStackTrace(Throwable throwableInformation) {
        try {
            if (throwableInformation == null) {
                return null;
            }
            return StackTraceUtils.getStackTrace(throwableInformation);
        } catch (Throwable e) {
            if (logger.isWarnEnabled() && ZeusLoggerConfig.needEnableLogger()) {
                logger.warn("### Zeus日志监控模块, Log4j日志监控服务加工堆栈信息出现异常:", e);
            }
        }
        return null;
    }

    @Override
    public void append(LogEvent event) {
        try {
            if (event != null && event.getLevel().isMoreSpecificThan(Level.ERROR)) {
                // 开关
                if (!ZeusContext.getContext().alarmEnable()) {
                    return;
                }
                // 内容是否可以忽略
                if (ZeusContext.getContext().checkAlarmContentIgnore(event.getLoggerName(),
                                                                     event.getMessage().toString(), getStackTrace(event.getThrown()))) {
                    return;
                }

                // 发送报告
                ZeusReportClient client = new ZeusReportLog4j2Client(event);
                client.complete();
            }
        } catch (Throwable e) {
            if (logger.isWarnEnabled() && ZeusLoggerConfig.needEnableLogger()) {
                logger.warn("### Zeus日志监控模块, Log4j日志监控服务执行失败，错误信息 >> errMsg = {}", e.getMessage());
            }
        }
    }
}
